(in-package :context-indexing)

(defun make-particle (rank &key distribution)
  (let ((particle (make-array rank :element-type 'single-float 
                                   :initial-element .0)))
    (if distribution 
        (nnormalize (map-into1 (generator (funcall distribution)) particle)) 
        particle)))

(defun pull (particle center charge)
  (declare #.*standard-optimize-settings*)
  (nnormalize (nvector+* particle (vector- center particle) charge)))
  
(defun center (particles &optional mass)
  (declare #.*standard-optimize-settings*)
  (let ((center (make-particle (length (aref particles 0)))))
    (nnormalize (if mass
                    (foldl #'nvector+* center particles mass)
                    (foldl #'nvector+ center particles)))))
        
(defun context (particles &key (charge .01) mass)
  (let ((center (center particles mass)))
    (if (arrayp charge) 
        (map nil (op pull _  center _) particles charge)
        (map nil (op pull _ center charge) particles))))
